import cgi
import os
import urllib
import logging
import rating
import pickle

from google.appengine.api import users
from google.appengine.ext import webapp
from google.appengine.ext.webapp.util import run_wsgi_app
from google.appengine.ext import db
from google.appengine.ext.webapp import template
from google.appengine.api import memcache

from datetime import datetime, date, time, timedelta

# Set the debug level
_DEBUG = True

MAX_TABLE = 1000000
  
class ParticipationStatus:
  Unknown=0
  Observer=1
  WhitePlayer=2
  BlackPlayer=3
  
  
class Color:
  White = 0
  Black = 1
  Unknown = 2

class Direction:
  Horizontal = 0
  Vertical = 1
  Unknown = 2

class ActionType:
  Split = 0;
  Merge = 1;
  Unknown = 2;

class Point(object):
  def __init__(self, x, y):
    self.x = x;
    self.y = y;


#class Move(object):
#  color = Color.Unknown
#  split_direction = Direction.Unknown
#  action_type = ActionType.Unknown
#  swap_sequence = []
#  start_piece = None
#  end_piece = None
  

class Table(db.Model, object):   
  table_number = db.IntegerProperty()
  table_number_str = "unknown"
  participants = []
  
  def __init__(self, table_number, *args, **kwargs):
    super(Table, self).__init__(*args, **kwargs)
    self.table_number = table_number
    self.table_number_str = str(table_number)
    
class Game(db.Model, object):
  table_number = db.StringProperty(default="")
  player_white = db.UserProperty()
  player_black = db.UserProperty()
  started = db.DateTimeProperty()
  last_move_id = db.IntegerProperty(default=0)
  pickled_data = db.BlobProperty(required=False)
  winner = db.IntegerProperty(default = Color.Unknown)

  
  def __init__(self, *args, **kwargs):
    super(Game, self).__init__(*args, **kwargs)
    if self.pickled_data:
      (self.moves) = pickle.loads(self.pickled_data)
    else: 
      self.moves = [""]
  
  def put(self):
       '''Stores the object, making the derived fields consistent.'''
       # Pickle data
       self.pickled_data = pickle.dumps((self.moves), 2)
       db.Model.put(self)
       if (self.table_number == ""):
         self.table_number = str(MAX_TABLE + self.key().id())
         db.Model.put(self)
 
      
class Greeting(db.Model):
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)
  table_number = db.StringProperty()
  
class CrumbleUser(db.Model):
  email = db.StringProperty()
  nickname = db.StringProperty()
  joined = db.DateTimeProperty(auto_now_add=True)
  picture = db.StringProperty()
  rating = db.IntegerProperty()
  number_of_games_played = db.IntegerProperty()
  
  def __init__(self, *args, **kwargs):
    super(CrumbleUser, self).__init__(*args, **kwargs)
    if (self.rating == None):
      self.rating = rating.DEFAULT_RATING
    if (self.number_of_games_played == None):
      self.number_of_games_played = 0
    
class ChatContent(db.Model):
  author = db.UserProperty()
  content = db.StringProperty(multiline=True)
  date = db.DateTimeProperty(auto_now_add=True)

class Singleton(object):
     """ A Pythonic Singleton """
     def __new__(cls, *args, **kwargs):
         if '_inst' not in vars(cls):
             cls._inst = object.__new__(cls, *args, **kwargs)
         return cls._inst

def get_greetings(table_number):
  return db.GqlQuery("SELECT * FROM Greeting WHERE table_number=:1 ORDER BY date", table_number).fetch(1000);
  
def get_game(table_number):
  game = db.GqlQuery("SELECT * FROM Game WHERE table_number=:1", table_number).get()
  if (game != None):
      logging.debug("Found game for table " + table_number + " white " + str(game.player_white) + "; black " + str(game.player_black))
  return game

def get_crumble_user(user):
    logging.debug("get_crumble_user " + user.email())
    crumble_users = db.GqlQuery("SELECT * FROM CrumbleUser WHERE email=:1", user.email()).fetch(1) 
    crumble_user = None
    if (crumble_users and len(crumble_users) > 0):
        crumble_user = crumble_users[0]
    if (crumble_user == None):
       logging.debug("User not found, crating")
       crumble_user = CrumbleUser();
       crumble_user.email = user.email()
       crumble_user.nickname = user.nickname()
       crumble_user.put()
    return crumble_user
  
# TODO: move away from tables, just use table numbers
def get_updated_table(table_number):
  table = Table(int(table_number))
  table.participants = db.GqlQuery("SELECT * FROM CrumbleUser WHERE table_number=:1", table_number).fetch(100)
  table.game = get_game(table_number);
  return table
